import imhere.exceptions.IPMissingException;
import imhere.exceptions.InvalidEMailException;
import imhere.exceptions.InvalidIPAdressException;
import imhere.exceptions.InvalidPhoneNumberException;
import imhere.exceptions.RequiredEmailMissingException;
import imhere.exceptions.RequiredNameMissingException;
import imhere.exceptions.UserAlreadyInvitedException;
import imhere.exceptions.UserAlreadySharedException;
import imhere.exceptions.UserNotFoundException;

import java.util.List;

/**
 * 
 * The interface for objects which have a username, password and a location by
 * IP.
 * 
 * @author Alexandre, Cristovao, Raul, Rodolpho, Tales
 * 
 */
public interface UserLoggable {

	/**
	 * Check if a IP is valid.
	 * 
	 * @param ip
	 * @return true - is valid IP false - isn't invalid IP
	 */
	boolean isIPValid(String iPaddress) throws IPMissingException;

	/**
	 * Return the userName
	 * 
	 * @return userNme
	 */
	String getUserName();

	/**
	 * Returns the password
	 * 
	 * @return password of the user
	 */
	String getPassword();

	/**
	 * Set new password for the user.
	 * 
	 * @param password
	 *            the new password
	 */
	void setPassword(String password) throws Exception;

	/**
	 * Return the full name of the User
	 * 
	 * @return name full name of the user
	 */
	String getName();

	/**
	 * Set new name for the user
	 * 
	 * @param name
	 *            a new full name of the user
	 * @throws RequiredNameMissingException
	 *             - if pass a invalid name
	 */
	void setName(String name) throws RequiredNameMissingException;

	/**
	 * Return email of the user
	 * 
	 * @return email
	 */
	String getEmail();

	/**
	 * Set new email to the user account
	 * 
	 * @param email
	 * @throws RequiredEmailMissingException
	 *             if pass a invalid email.
	 */
	void setEmail(String email) throws RequiredEmailMissingException,
			InvalidEMailException;

	/**
	 * Return phone number of the user
	 * 
	 * @return phoneNumber
	 */
	String getPhoneNumber();

	/**
	 * Set new phone Number for the user.
	 * 
	 * @param phoneNumber
	 */
	void setPhoneNumber(String phoneNumber) throws InvalidPhoneNumberException;

	/**
	 * Return ID of the user
	 * 
	 * @return id
	 */
	Long getId();

	/**
	 * Set new ID for the user.
	 * 
	 * @param id
	 */
	void setId(Long id);

	/**
	 * Set a IP for the user
	 * 
	 * @param ip
	 * @throws Exception
	 *             if pass IP is invalid
	 */
	void setIP(String ip) throws IPMissingException, InvalidIPAdressException;

	/**
	 * Update attributes of user
	 * 
	 * @param modifiedUser
	 *            the new user modified
	 */
	void updateAttributes(UserLoggable modifiedUser);

	/**
	 * Set Location of a user with latitude and longitude.
	 * 
	 * @param latitude
	 * @param longitude
	 */
	void setLocation(String latitude, String longitude);

	/**
	 * Return location of the user
	 * 
	 * @return the location of the user in format "Lat: xxx, Long: xxx"
	 * @throws Exception
	 *             if location is invalid (null)
	 */
	String getLocation() throws Exception;

	/**
	 * Return IP of the user
	 * 
	 * @return IP
	 */
	String getIp();

	/**
	 * Return latitude of the user
	 * 
	 * @return latitude
	 */
	String getLatitude();

	/**
	 * Set latitude of the user
	 * 
	 * @param latitude
	 */
	void setLatitude(String latitude);

	/**
	 * Return longitude of the user
	 * 
	 * @return longitude
	 */
	String getLongitude();

	/**
	 * Set longitude of the user
	 * 
	 * @param longitude
	 */
	void setLongitude(String longitude);

	/**
	 * Insert user in friend list
	 * 
	 * @param user
	 *            friend
	 * @param mode
	 *            - (1) HIDDEN (2) VISIBLE
	 * @throws if user is already on friend list
	 */
	void insertFriend(UserLoggable user1, int exibir)
			throws UserAlreadySharedException;

	/**
	 * Return friends list of the user in String format
	 * 
	 * @return friendList in String format
	 */
	String getFriendList();

	/**
	 * Add a invitation on the list of pending invites
	 * 
	 * @param invite
	 *            - a new invite
	 */
	public void addPendingInvitation(Invite invite)
			throws UserAlreadyInvitedException;

	/**
	 * Remove a invitation from the list of pending
	 * 
	 * @param email
	 *            of the user
	 */
	public void removePendingInvitation(String email);

	/**
	 * Return a list of the pending invites on the system
	 * 
	 * @return invites
	 */
	public String getPendingInvitations();

	/**
	 * Check if the user can view when his friend is online
	 * 
	 * @param friend
	 * @return true - if the user can see when his friend is online false - if
	 *         the user can't see his friend
	 * @throws if the friend isn't the friends list of the user
	 */
	boolean canISeeYourLocation(UserLoggable userByUserName)
			throws UserNotFoundException;

	/**
	 * Set mode of sharing with friends
	 * 
	 * @param friend
	 * @param mode
	 *            (1) HIDDEN // (2) VISIBLE
	 */
	void setSharing(UserLoggable friend, int mode);

	/**
	 * Remove a friend from the userlist of the user
	 * 
	 * @param userFriend
	 * @throws if the user isn't in the userlist
	 */
	void removeFriend(UserLoggable userFriend) throws UserNotFoundException;

	/**
	 * Return friends list of the user in List format
	 * 
	 * @return List friends
	 */
	public List<UserLoggable> getFriendsList();

	/**
	 * Return all sharing friends mode of the user in List format
	 * 
	 * @return sharing mode (1) HIDDEN /// (2) VISIBLE
	 */
	public List<Integer> getSharingMode();

	/**
	 * Check if the password is default
	 * 
	 * @return true - if the password is default false - if the password isn't
	 *         default
	 */
	public boolean isStandardPassword();

}
